using System.Diagnostics;
using System.Globalization;
using System.Web;
using System.Web.UI;
using CLFramework.Globalization;

namespace CLFramework.Web.Globalization
{
    /// <summary>
    /// For read global resources in App_GlobalResources.
    /// </summary>
    public class WebResourceReader : IResource
    {
        #region Variable

        /// <summary>
        /// Global resource name.
        /// </summary>
        public const string GlobalResourceName = "global";

        private readonly string appThemesRoot;
        private readonly string imagesRoot;
        private readonly CultureInfo culture;
        private readonly string imageCulturePath;
        private readonly string currentResourceClass;

        #endregion

        #region Constructor

        /// <summary>
        /// Initializes a new instance of the <see cref="WebResourceReader"/> class.
        /// </summary>
        public WebResourceReader(Page page)
        {
            //get system name by url
            currentResourceClass = GetResourceClass(page.Request);
            //get current culture
            culture = GlobalSettings.CurrentCulture;

            if (appThemesRoot == null)
            {
                string appBasePath = page.Request.ApplicationPath.TrimEnd('/');
                appThemesRoot = string.Concat(appBasePath, "/App_Themes/", page.Theme, "/");
                imagesRoot = string.Concat(appThemesRoot, "Images/");
            }
            //get imange path with culture info
            imageCulturePath = string.Concat(ImagesRoot, GlobalSettings.CurrentLanguage, "/");
        }

        #endregion

        #region Property

        /// <summary>
        /// Gets the root path of AppThemes
        /// </summary>
        public string AppThemesRoot
        {
            [DebuggerStepThrough]
            get { return appThemesRoot; }
        }

        /// <summary>
        /// Gets the root path of images.
        /// </summary>
        public string ImagesRoot
        {
            [DebuggerStepThrough]
            get { return imagesRoot; }
        }

        /// <summary>
        /// Gets the resource name of the current system.
        /// </summary>
        /// <value>The name of the system resource.</value>
        public string CurrentResourceClass
        {
            [DebuggerStepThrough]
            get { return currentResourceClass; }
        }

        #endregion

        #region GetResourceClass

        /// <summary>
        /// Gets the current resource class name by url.
        /// </summary>
        /// <returns></returns>
        private static string GetResourceClass(HttpRequest httpRequest)
        {
            string name = string.Empty;

            string[] segments = httpRequest.Url.Segments;

            if ((segments.Length > 2)
                && (segments[1].Trim('/').ToLower() != httpRequest.ApplicationPath.Trim('/').ToLower()))
            {
                name = "." + segments[1];
            }

            for (int i = 2; i < segments.Length - 1; i++)
            {
                name += "." + segments[i];
            }

            name = (name == string.Empty) ? GlobalResourceName : name.Substring(1).Replace("/", "").Trim().ToLower();

            return name;
        }

        #endregion

        #region GetString

        /// <summary>
        /// Get string from resource by specified resource key.
        /// </summary>
        /// <param name="resourceKey">The resource key.</param>
        /// <returns>Resource value.</returns>
        /// <remarks>The sequence for search resource: CurrentModule -&gt; Global</remarks>
        public virtual string GetString(string resourceKey)
        {
            return GetString(null, resourceKey);
        }

        /// <summary>
        /// Gets the string by resource name and key
        /// </summary>
        /// <param name="classKey">The class key. Such as: usermanagement, it will mapping usermanagement.resx</param>
        /// <param name="resourceKey">The resource key.</param>
        /// <returns>Resource value</returns>
        /// <remarks>The sequence for search resource: SpecifiedModule -> CurrentModule -&gt; Global</remarks>
        public string GetString(string classKey, string resourceKey)
        {
            string result;

            if (Checker.IsNotEmpty(classKey))
            {
                //From specified module
                result = HttpContext.GetGlobalResourceObject(classKey, resourceKey, culture) as string;
                if (result != null)
                {
                    return result;
                }
            }

            //From current module
            result = HttpContext.GetGlobalResourceObject(CurrentResourceClass, resourceKey, culture) as string;
            if (result != null)
            {
                return result;
            }

            //From global resource pool.
            result = HttpContext.GetGlobalResourceObject(GlobalResourceName, resourceKey, culture) as string;
            if (result != null)
            {
                return result;
            }

            //return resource key.
            return resourceKey;
        }

        #endregion

        #region GetImage

        /// <summary>
        /// Gets the image.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <returns></returns>
        /// <example>
        /// 	<code>GetImage("Control.DataGrid.Asc.gif");</code>
        /// </example>
        public string GetImage(string name)
        {
            return string.Concat(imageCulturePath, name);
        }

        /// <summary>
        /// Gets the image.
        /// </summary>
        /// <param name="path">Sub folder path from image root path.</param>
        /// <param name="name">The name.</param>
        /// <returns></returns>
        /// <example>
        /// 	<code>GetImage("top", "topmenubg.gif");</code>
        /// </example>
        public string GetImage(string path, string name)
        {
            if (!path.EndsWith("/"))
            {
                path += "/";
            }

            return string.Concat(ImagesRoot, path, name);
        }

        #endregion

        #region GetThemesResourceUrl

        /// <summary>
        /// Gets the themes resource URL.
        /// </summary>
        /// <param name="resourceName">Name of the resource.</param>
        /// <returns></returns>
        public string GetThemesResourceUrl(string resourceName)
        {
            return string.Concat(AppThemesRoot, resourceName);
        }

        #endregion

        #region GetObject

        /// <summary>
        /// Get object from resource by name.
        /// </summary>
        /// <param name="name">Name.</param>
        /// <returns>Value.</returns>
        public virtual object GetObject(string name)
        {
            return GetObject(null, name);
        }

        /// <summary>
        /// Get object from resource by name.
        /// </summary>
        /// <param name="resourceName">Name of the resource.</param>
        /// <param name="name">Name.</param>
        /// <returns>Value.</returns>
        public object GetObject(string resourceName, string name)
        {
            object result;

            if (Checker.IsNotEmpty(resourceName))
            {
                //From specified module
                result = HttpContext.GetGlobalResourceObject(resourceName, name, culture);
                if (result != null)
                {
                    return result;
                }
            }

            //From current module
            result = HttpContext.GetGlobalResourceObject(CurrentResourceClass, name, culture);
            if (result != null)
            {
                return result;
            }

            //From global resource pool.
            result = HttpContext.GetGlobalResourceObject(GlobalResourceName, name, culture);
            if (result != null)
            {
                return result;
            }

            return null;
        }

        #endregion
    }
}